﻿using CLCommuModbus.Config;
using CLVisionModbus;
using IniParser;
using IniParser.Model;
using NationalInstruments.TestStand.Interop.API;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using CLVisionCommuInterface;
using System.Collections.Concurrent;
using System.Net;

namespace CLCommuModbus
{
    public partial class CommuCaller : ICLVisionCommu
    {
        int threadCount;
        string ip;
        int port;
        string interfaceDLL;
        ConstantConfigOption constantConfigOption;
        ObjectConfigOption objectConfigOption;
        CLVisionModbusSlave cLVisionModbusSlave;
        public bool Init(int threadIndex, string configFilePath, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
                //读配置参数
                ip = ReadIniFile(configFilePath, "Thread" + threadIndex.ToString(), "IP", out ErrorCode, out ErrorText);
                if (ErrorCode == -1) { return false; }
                port = Convert.ToInt32(ReadIniFile(configFilePath, "Thread" + threadIndex.ToString(), "Port", out ErrorCode, out ErrorText));
                if (ErrorCode == -1) { return false; }
                interfaceDLL = ReadIniFile(configFilePath, "Thread" + threadIndex.ToString(), "InterfaceDLL", out ErrorCode, out ErrorText); //============
                if (ErrorCode == -1) { return false; }
                CreateConnect(ip, port, out cLVisionModbusSlave, out ErrorCode, out ErrorText);
                if (ErrorCode == -1) { return false; }
                //配置固定地址参数
                constantConfigOption = new ConstantConfigOption();
                constantConfigOption.SetConstant_handShakeMode2();

                //配置Object参数
                //string ObjectConfigFilePath = @"C:\Users\hao.chen\Desktop\OnjecthandShakeMode2.cdat";
                string ObjectConfigFilePath = Path.Combine(Path.GetDirectoryName(configFilePath), "ObjecthandShakeMode2.cdat");

                objectConfigOption = new ObjectConfigOption();
                objectConfigOption.SetObject_handShakeMode2(ObjectConfigFilePath);//==============
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "初始化通讯、参数失败！" + ex.Message;
                return false;
            }
        }

        public bool ReceiveConstantData(string constantName, out double value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            value = -1;
            try
            {
                if (constantName != "" && constantConfigOption.constantValuesDict.ContainsKey(constantName))
                {
                    int address = constantConfigOption.constantValuesDict[constantName].Address;
                    DataType dataType = constantConfigOption.constantValuesDict[constantName].DataType;
                    ModbusDataType modbusDataType = constantConfigOption.constantValuesDict[constantName].ModbusDataType;
                    bool isBit = constantConfigOption.constantValuesDict[constantName].IsBit;
                    int bitIndex = constantConfigOption.constantValuesDict[constantName].BitIndex;
                    object constantValue = ReadFromPLC(address, dataType, modbusDataType, out ErrorCode, out ErrorText);
                    if (ErrorCode == -1) { return false; }
                    if (isBit)
                    {
                        bool[] bools = ConvertData.UshortToBoolArray(Convert.ToUInt16(constantValue));
                        value = Convert.ToDouble(bools[bitIndex]);
                    }
                    else
                    {
                        value = Convert.ToDouble(constantValue);
                    }
                    return true;
                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"{constantName}：名称有误！";
                    return false;
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "接收固定地址返回值失败！" + ex.Message;
                return false;
            }
        }

        public bool ReceiveObjectData(int objectID, PropertyObject containerToReceiveValue, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
                HandShakeMode handShakeMode = HandShakeMode.HandShakeMode2;
                //********************** object ************************
                switch (handShakeMode)
                {
                    case HandShakeMode.HandShakeMode1:

                        return true;
                    case HandShakeMode.HandShakeMode2:
                        ReadObjectValueFromPLC_handShakeMode2(objectID, containerToReceiveValue, out ErrorCode, out ErrorText);
                        return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "接收Object值失败！" + ex.Message;
                return false;
            }
        }

        public bool SendConstantData(string constantName, double constantValue, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
                if (constantName != "" && constantConfigOption.constantValuesDict.ContainsKey(constantName))
                {
                    int address = constantConfigOption.constantValuesDict[constantName].Address;
                    DataType dataType = constantConfigOption.constantValuesDict[constantName].DataType;
                    ModbusDataType modbusDataType = constantConfigOption.constantValuesDict[constantName].ModbusDataType;
                    WriteToPLC(address, dataType, constantValue, modbusDataType, out ErrorCode, out ErrorText);
                    if (ErrorCode == -1) { return false; }
                    return true;
                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"{constantName}：名称有误！";
                    return false;
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "发送固定地址返回值失败！" + ex.Message;
                return false;
            }
        }

        public bool SendObjectData(int objectID, PropertyObject containerToSendValue, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
                HandShakeMode handShakeMode = HandShakeMode.HandShakeMode2;
                //********************** object ************************
                switch (handShakeMode)
                {
                    case HandShakeMode.HandShakeMode1:

                        return true;
                    case HandShakeMode.HandShakeMode2:
                        WriteObjectValueToPLC_handShakeMode2(objectID, containerToSendValue, out ErrorCode, out ErrorText);
                        return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "发送Object值失败！" + ex.Message;
                return false;
            }
        }


    }
}
